package com.xxl.job.executor.core.config;

import com.alibaba.fastjson.JSONObject;
import com.ruoyi.business.common.AsyncService;
import com.ruoyi.business.util.BathJobMonitorUtil;
import com.ruoyi.common.utils.DateUtils;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.log.XxlJobFileAppender;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * @Author:
 * @Description: xxljob执行方法的切面
 * @DateTime: 2021/12/26 23:09
 **/
@Aspect
@Component
public class XxlJobAspect {

    @Autowired
    AsyncService asyncService;

    @Autowired
    BathJobMonitorUtil bathJobMonitorUtil;

    public static final String XXL_JOB_LOG_PATH = "xxlJobLogPath";

    /**
     * 线程本地变量
     */
    private static ThreadLocal<Date> threadLocal = new ThreadLocal<>();

    @Pointcut("@annotation(com.xxl.job.core.handler.annotation.XxlJob)")
    public void execute() {
    }

    @Before("execute()")
    public void before() {
        // 记录开始时间
        threadLocal.set(new Date());

        String xxlJobLogPath = XxlJobFileAppender.getLogPath();
        MDC.put(XXL_JOB_LOG_PATH, xxlJobLogPath);
    }

    @After("execute()")
    public void after(JoinPoint joinPoint) {
        // 记录结束时间
        Date endTime = new Date();
        // 打印耗时日志
        XxlJobHelper.log(">>>>> {} 任务耗时：{} s", getJobName(joinPoint), (endTime.getTime() - threadLocal.get().getTime()) / 1000);

        MDC.remove(XXL_JOB_LOG_PATH);
    }

    // 环绕通知需要得知方法的参数 (一个接口方法的参数)
//    @Around("execute()")
//    public Object aroundJob(ProceedingJoinPoint pjp) {
//        //清理缓存
//        String jobName = getJobName(pjp);
//        bathJobMonitorUtil.clearRedis(jobName);
//
//        try {
//            Object result = pjp.proceed();
//            //删除缓存
//            bathJobMonitorUtil.delRedis(jobName);
//            return result;
//        } catch (Throwable t) {
//            XxlJobHelper.log(">>>>> {} 任务处理异常：", jobName);
//            XxlJobHelper.log(t);
//        }
//        return null;
//    }

    @AfterThrowing(pointcut = "execute()", throwing = "ex")
    public void doAfterThrowing(JoinPoint joinPoint, Exception ex) {

        String jobName = getJobName(joinPoint);
        XxlJobHelper.log(">>>>> {} 任务执行异常：", jobName);
        XxlJobHelper.log(ex);

        // 报错发消息
        JSONObject content = new JSONObject();
        content.put("Time", DateUtils.dateTimeNow("yyyy-MM-dd HH:mm:ss"));
        content.put("ClassName", jobName);
        content.put("Error", ex.getMessage());

        asyncService.sendFeishu("monitor-group", "BatchJobError", content);
    }

    private String getJobName(JoinPoint joinPoint) {
        String name = joinPoint.getSignature().getDeclaringType().getName();
        String[] split = name.split("\\.");
        String apiName = split[split.length - 1];
        return apiName;
    }
}

